Shader "Unlit/FurShell"
{
    Properties
    {
        _MainTex ("Base Texture", 2D) = "white" {}
        _FurLength ("Fur Length", Range(0.0, 0.2)) = 0.05
        _FurDensity ("Fur Density", Range(0.1, 5.0)) = 1.0
        _FurShells ("Fur Shells", Range(1, 50)) = 20
        _FurGravity ("Fur Gravity", Range(-1.0, 1.0)) = 0.2
        _FurColorRoot ("Root Color", Color) = (0.2, 0.1, 0.05, 1.0)
        _FurColorTip ("Tip Color", Color) = (0.8, 0.7, 0.6, 1.0)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100
        
        
        // 简化但有效的壳层实现
        Pass
        {
            Cull Off
            ZWrite On
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            int _FurShells;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
        
        // 壳层Passes - 重复多次以创建毛发效果
        Pass
        {
            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"
            
            #define FUR_LAYER 0.05

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float furDepth : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            int _FurShells;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                
                // 添加随机扰动
                float rand = frac(sin(dot(v.vertex.xyz, float3(12.9898, 78.233, 37.719))) * 43758.5453);
                float3 noise = float3(rand, rand * rand, sin(rand * 6.28)) * 0.1;
                
                // 法线扰动
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                worldNormal = normalize(worldNormal + noise * 0.3);
                
                // 重力效果
                worldNormal.y -= _FurGravity * FUR_LAYER * 0.5;
                worldNormal = normalize(worldNormal);
                
                // 毛发生长
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                worldPos += worldNormal * _FurLength * FUR_LAYER;
                
                o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                o.furDepth = FUR_LAYER;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 baseColor = tex2D(_MainTex, i.uv);
                fixed4 furColor = lerp(_FurColorRoot, _FurColorTip, i.furDepth) * baseColor;
                
                // 透明度计算
                float alpha = 1.0 - i.furDepth;
                alpha *= smoothstep(0.0, 0.2, i.furDepth);
                alpha *= saturate(_FurDensity) * 0.7;
                
                furColor.a = alpha;
                UNITY_APPLY_FOG(i.fogCoord, furColor);
                return furColor;
            }
            ENDCG
        }
        
        // 生成多个壳层Pass
        Pass
        {
            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"
            
            #define FUR_LAYER 0.15

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float furDepth : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                
                float rand = frac(sin(dot(v.vertex.xyz, float3(12.9898, 78.233, 37.719))) * 43758.5453);
                float3 noise = float3(rand, rand * rand, sin(rand * 6.28)) * 0.1;
                
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                worldNormal = normalize(worldNormal + noise * 0.3);
                
                worldNormal.y -= _FurGravity * FUR_LAYER * 0.5;
                worldNormal = normalize(worldNormal);
                
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                worldPos += worldNormal * _FurLength * FUR_LAYER;
                
                o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                o.furDepth = FUR_LAYER;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 baseColor = tex2D(_MainTex, i.uv);
                fixed4 furColor = lerp(_FurColorRoot, _FurColorTip, i.furDepth) * baseColor;
                
                float alpha = 1.0 - i.furDepth;
                alpha *= smoothstep(0.0, 0.2, i.furDepth);
                alpha *= saturate(_FurDensity) * 0.7;
                
                furColor.a = alpha;
                UNITY_APPLY_FOG(i.fogCoord, furColor);
                return furColor;
            }
            ENDCG
        }
        
        Pass
        {
            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"
            
            #define FUR_LAYER 0.3

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float furDepth : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                
                float rand = frac(sin(dot(v.vertex.xyz, float3(12.9898, 78.233, 37.719))) * 43758.5453);
                float3 noise = float3(rand, rand * rand, sin(rand * 6.28)) * 0.1;
                
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                worldNormal = normalize(worldNormal + noise * 0.3);
                
                worldNormal.y -= _FurGravity * FUR_LAYER * 0.5;
                worldNormal = normalize(worldNormal);
                
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                worldPos += worldNormal * _FurLength * FUR_LAYER;
                
                o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                o.furDepth = FUR_LAYER;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 baseColor = tex2D(_MainTex, i.uv);
                fixed4 furColor = lerp(_FurColorRoot, _FurColorTip, i.furDepth) * baseColor;
                
                float alpha = 1.0 - i.furDepth;
                alpha *= smoothstep(0.0, 0.2, i.furDepth);
                alpha *= saturate(_FurDensity) * 0.7;
                
                furColor.a = alpha;
                UNITY_APPLY_FOG(i.fogCoord, furColor);
                return furColor;
            }
            ENDCG
        }
        
        Pass
        {
            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"
            
            #define FUR_LAYER 0.5

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float furDepth : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                
                float rand = frac(sin(dot(v.vertex.xyz, float3(12.9898, 78.233, 37.719))) * 43758.5453);
                float3 noise = float3(rand, rand * rand, sin(rand * 6.28)) * 0.1;
                
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                worldNormal = normalize(worldNormal + noise * 0.3);
                
                worldNormal.y -= _FurGravity * FUR_LAYER * 0.5;
                worldNormal = normalize(worldNormal);
                
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                worldPos += worldNormal * _FurLength * FUR_LAYER;
                
                o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                o.furDepth = FUR_LAYER;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 baseColor = tex2D(_MainTex, i.uv);
                fixed4 furColor = lerp(_FurColorRoot, _FurColorTip, i.furDepth) * baseColor;
                
                float alpha = 1.0 - i.furDepth;
                alpha *= smoothstep(0.0, 0.2, i.furDepth);
                alpha *= saturate(_FurDensity) * 0.7;
                
                furColor.a = alpha;
                UNITY_APPLY_FOG(i.fogCoord, furColor);
                return furColor;
            }
            ENDCG
        }
        
        Pass
        {
            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"
            
            #define FUR_LAYER 0.7

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float furDepth : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                
                float rand = frac(sin(dot(v.vertex.xyz, float3(12.9898, 78.233, 37.719))) * 43758.5453);
                float3 noise = float3(rand, rand * rand, sin(rand * 6.28)) * 0.1;
                
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                worldNormal = normalize(worldNormal + noise * 0.3);
                
                worldNormal.y -= _FurGravity * FUR_LAYER * 0.5;
                worldNormal = normalize(worldNormal);
                
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                worldPos += worldNormal * _FurLength * FUR_LAYER;
                
                o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                o.furDepth = FUR_LAYER;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 baseColor = tex2D(_MainTex, i.uv);
                fixed4 furColor = lerp(_FurColorRoot, _FurColorTip, i.furDepth) * baseColor;
                
                float alpha = 1.0 - i.furDepth;
                alpha *= smoothstep(0.0, 0.2, i.furDepth);
                alpha *= saturate(_FurDensity) * 0.7;
                
                furColor.a = alpha;
                UNITY_APPLY_FOG(i.fogCoord, furColor);
                return furColor;
            }
            ENDCG
        }
        
        Pass
        {
            Cull Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"
            
            #define FUR_LAYER 0.9

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float furDepth : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FurLength;
            float _FurDensity;
            float _FurGravity;
            float4 _FurColorRoot;
            float4 _FurColorTip;

            v2f vert (appdata v)
            {
                v2f o;
                
                float rand = frac(sin(dot(v.vertex.xyz, float3(12.9898, 78.233, 37.719))) * 43758.5453);
                float3 noise = float3(rand, rand * rand, sin(rand * 6.28)) * 0.1;
                
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                worldNormal = normalize(worldNormal + noise * 0.3);
                
                worldNormal.y -= _FurGravity * FUR_LAYER * 0.5;
                worldNormal = normalize(worldNormal);
                
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                worldPos += worldNormal * _FurLength * FUR_LAYER;
                
                o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex);
                o.furDepth = FUR_LAYER;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 baseColor = tex2D(_MainTex, i.uv);
                fixed4 furColor = lerp(_FurColorRoot, _FurColorTip, i.furDepth) * baseColor;
                
                float alpha = 1.0 - i.furDepth;
                alpha *= smoothstep(0.0, 0.2, i.furDepth);
                alpha *= saturate(_FurDensity) * 0.7;
                
                furColor.a = alpha;
                UNITY_APPLY_FOG(i.fogCoord, furColor);
                return furColor;
            }
            ENDCG
        }
    }
    
    FallBack "Transparent/VertexLit"
}
